package cn.xxm.scene.controller;

import cn.xxm.scene.bo.ModelExcel;
import cn.xxm.scene.listener.ExcelListener;
import cn.xxm.scene.service.EasyService;
import cn.xxm.scene.utils.ExcelUtil;
import cn.xxm.scene.utils.FileConfig;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Controller
@Slf4j
public class EasyExcelController {

    @Autowired
    private EasyService easyService;

    /**
     * 首页
     *
     * @return
     */
    @GetMapping(value = {"/index", "/"})
    public String index() {
        return "index";
    }


    @PostMapping("/upload")
    @ResponseBody
    public String excelImport(@RequestParam(value = "fileName") MultipartFile serviceFile) throws IOException {
        if (serviceFile.isEmpty()) {
            return "空文件";
        }
        //获取文件名
        String fileName = serviceFile.getOriginalFilename();
        //获取文件后缀
        String type = fileName.indexOf(".") != -1 ? fileName.split("[.]")[1] : null;
        //文件格式判断
        if (!FileConfig.UPLOAD_EXCEL_TYPES.contains(type.toLowerCase())) {
            return "文件类型不对";
        }

        ExcelReader excelReader = null;
        InputStream in = null;
        try {
            in = serviceFile.getInputStream();
            excelReader = EasyExcel.read(in, ModelExcel.class, new ExcelListener()).build();
            ReadSheet readSheet = EasyExcel.readSheet(0).build();
            excelReader.read(readSheet);
        } catch (IOException ex) {
            log.error("import excel to db fail", ex);
        } finally {
            in.close();
            // 这里一定别忘记关闭，读的时候会创建临时文件，到时磁盘会崩
            if (excelReader != null) {
                excelReader.finish();
            }
        }
        return "success";
    }


    /**
     * 下载Excel模板
     */
    @GetMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response) {
        String fileName = "导入白名单模板";
        String sheetName = "导入白名单模板";
        JSONObject jsonObject = easyService.testKafka(fileName);
        List<ModelExcel> userList = new ArrayList<>();
        userList.add(new ModelExcel("1.1", "12345678", "847064370@qq.com"));
        userList.add(new ModelExcel("1.1", "12345679", "666666@qq.com"));
        try {
            ExcelUtil.writeExcel(response, userList, fileName, sheetName, ModelExcel.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 下载多个文件 并压缩成一个zip文件夹输出
     */
    @GetMapping("/downloadMultiFile")
    public void downloadMultiFileToZip(HttpServletResponse response) {
        String fileName = "请叫我鸣哥";
        String filePath = "/Users/mac/data/upload";
        fileToZip(filePath, fileName, response);
    }


    private boolean fileToZip(String sourceFilePath, String fileName, HttpServletResponse response) {
        boolean flag = false;
        File sourceFile = new File(sourceFilePath);
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        OutputStream fos = null;
        ZipOutputStream zos = null;

        if (sourceFile.exists() == false) {
            System.out.println(">>>>>> 待压缩的文件目录：" + sourceFilePath + " 不存在. <<<<<<");
        } else {
            try {
                File[] sourceFiles = sourceFile.listFiles();
                if (null == sourceFiles || sourceFiles.length < 1) {
                    System.out.println(">>>>>> 待压缩的文件目录：" + sourceFilePath + " 里面不存在文件,无需压缩. <<<<<<");
                } else {
                    //fos = new FileOutputStream(zipFile);
                    response.setHeader("Accept-Ranges", "bytes");
                    response.setContentType("application/octet-Stream");
                    response.addHeader("Content-Type", "application/octet-stream");
                    response.addHeader("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\".zip;filename*=UTF-8''" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));

                    fos = response.getOutputStream();
                    zos = new ZipOutputStream(new BufferedOutputStream(fos));

                    byte[] bufs = new byte[1024 * 10];
                    for (int i = 0; i < sourceFiles.length; i++) {
                        // 创建ZIP实体,并添加进压缩包
                        ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
                        zos.putNextEntry(zipEntry);
                        // 读取待压缩的文件并写进压缩包里
                        fis = new FileInputStream(sourceFiles[i]);
                        bis = new BufferedInputStream(fis, 1024 * 10);
                        int read = 0;

                        while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                            zos.write(bufs, 0, read);
                        }
                    }
                    flag = true;
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new RuntimeException(e);

            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                try {
                    if (null != bis) bis.close();
                    if (null != zos) zos.close();

                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }

            }

        }
        return flag;
    }


}